package com.zw.mes.config.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description: 在两秒时间内， 根据 url 和 param 判断是否为相同请求。
 *
 * @author: China.sgl
 * @Date: 2020/9/22 13:37
 */
@Component
public class RepeatCommitInterceptor extends AbstractRepeatCommitInterceptor {

    private final String REQUEST_PARAMS = "requestParams";

    private final String REQUEST_TIME = "requestTime";

    private final String SESSION_REQUEST_KEY = "requestData";

    private int intervalTime = 2;

    @Override
    public boolean isRepeatSubmit(HttpServletRequest request) throws Exception {
        // 本次参数及系统时间
        String nowParams = new ObjectMapper().writeValueAsString(request.getParameterMap());
        Map<String, Object> nowDataMap = new HashMap<>(16);
        nowDataMap.put(REQUEST_PARAMS, nowParams);
        nowDataMap.put(REQUEST_TIME, System.currentTimeMillis());

        // 请求地址（作为存放session的key值）
        String url = request.getRequestURI();

        HttpSession session = request.getSession();
        Object sessionObj = session.getAttribute(SESSION_REQUEST_KEY);
        if (sessionObj != null) {
            Map<String, Object> sessionMap = (Map<String, Object>) sessionObj;
            if (sessionMap.containsKey(url)) {
                Map<String, Object> preDataMap = (Map<String, Object>) sessionMap.get(url);
                if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap)) {
                    return true;
                }
            }
        }
        Map<String, Object> sessionMap = new HashMap<>(16);
        sessionMap.put(url, nowDataMap);
        session.setAttribute(SESSION_REQUEST_KEY, sessionMap);
        return false;
    }

    /**
     * 判断参数是否相同
     *
     * @param nowMap 当前参数
     * @param preMap 之前参数
     * @return boolean
     */
    private boolean compareParams(Map<String, Object> nowMap, Map<String, Object> preMap) {
        String nowParams = (String) nowMap.get(REQUEST_PARAMS);
        String preParams = (String) preMap.get(REQUEST_PARAMS);
        return nowParams.equals(preParams);
    }

    /**
     * 判断两次请求时间间隔
     *
     * @param nowMap 当前时间
     * @param preMap 之前时间
     * @return boolean
     */
    private boolean compareTime(Map<String, Object> nowMap, Map<String, Object> preMap) {
        long time1 = (Long) nowMap.get(REQUEST_TIME);
        long time2 = (Long) preMap.get(REQUEST_TIME);
        return (time1 - time2) < (this.intervalTime * 1000);
    }
}

